﻿using System;
using System.Collections.Generic;
using TFramework.ECS.Collection;
using TFramework.ECS.Entity;
using TFramework.ECS.Group;
using TFramework.Extensions;
using TFramework.Extensions.VContainer;
using UniRx;


namespace TFramework.ECS.System.Handler
{
    public class TeardownSystemHandler : ISystemHandler
    {
        public readonly IEntityCollection EntityCollectionManager;
        public readonly IDictionary<ISystem, IDisposable> SystemSubscriptions;
        private bool isDisposed;
        public TeardownSystemHandler(IEntityCollection entityCollectionManager)
        {
            EntityCollectionManager = entityCollectionManager;
            SystemSubscriptions = new Dictionary<ISystem, IDisposable>();
        }

        public bool CanHandleSystem(ISystem system)
        { return system is ITeardownSystem; }

        public void SetupSystem(ISystem system)
        {
            var entityChangeSubscriptions = new CompositeDisposable();
            SystemSubscriptions.Add(system, entityChangeSubscriptions);

            var castSystem = (ITeardownSystem)system;
            var observableGroup = EntityCollectionManager.GetObservableGroup(system.Group);

            observableGroup.OnEntityRemoving
                .Subscribe(x => Teardown(castSystem, x))
                .AddTo(entityChangeSubscriptions);
        }

        private void Teardown(ITeardownSystem system, IEntity entity)
        {
            system.Teardown(entity);
        }

        public void DestroySystem(ISystem system)
        {
            if (isDisposed)
                return;
            SystemSubscriptions.RemoveAndDispose(system);
        }

        public void Dispose()
        {
            isDisposed = true;
            SystemSubscriptions.DisposeAll();
        }
    }
}
